{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "54bbf797",
   "metadata": {},
   "source": [
    "## A tutorial on the new RV code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "20311a12",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib\n",
    "import os\n",
    "import joblib\n",
    "import datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7f64de2b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "@RVM: initializing Radial Velocity Machine (RVM)...\n"
     ]
    }
   ],
   "source": [
    "# load rvm (this can be downloaded from paperdata repo)\n",
    "rvm = joblib.load(\"/Users/cham/projects/sb2/data/v10_rvm.dump\")\n",
    "# select 200 templates\n",
    "rvm = rvm.shrink(200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ff9d0969",
   "metadata": {},
   "outputs": [],
   "source": [
    "# synthesize test spectrum\n",
    "test_wave = rvm.wave_mod[(rvm.wave_mod>5000-5)&(rvm.wave_mod<5300+5)]\n",
    "test_flux = np.interp(test_wave, rvm.wave_mod*(1+123/299792.458), rvm.flux_mod[101])\n",
    "test_fluxerr = test_flux*0+.03"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a9f7a8cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "@RVM: making cache ...\n"
     ]
    }
   ],
   "source": [
    "# make cache\n",
    "rvm.make_cache(cache_name=\"B\", wave_range=(5000, 5300), rv_grid=(-1000, 1000, 10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2318aa9f",
   "metadata": {},
   "source": [
    "### no acceleration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9d8f6f30",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8.06 s ± 28.2 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit -r 3\n",
    "rvr = rvm.measure(test_wave, test_flux, cache_name=None, rv_grid=np.arange(-1000, 1001, 10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6dd80f0",
   "metadata": {},
   "source": [
    "### vectorization without cache"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c86a19fa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4.06 s ± 47 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit -r 3\n",
    "rvr = rvm.measure(test_wave, test_flux, cache_name=\"matrix\", rv_grid=np.arange(-1000, 1001, 10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "569560a1",
   "metadata": {},
   "source": [
    "### vectorization with cache"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "cd93f151",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "680 ms ± 4.37 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit -r 3\n",
    "# note that the rv grid is set in *make_cache*, no longer to input here\n",
    "rvr = rvm.measure(test_wave, test_flux, cache_name=\"B\", nmc=50)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ddd0bcf3",
   "metadata": {},
   "source": [
    "### vectorization with cache & bianry RV decomposition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "033947ad",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/cham/anaconda3/lib/python3.8/site-packages/scipy/optimize/optimize.py:2149: RuntimeWarning: invalid value encountered in double_scalars\n",
      "  tmp2 = (x - v) * (fx - fw)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "749 ms ± 10.6 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit -r 3\n",
    "rvr = rvm.measure_binary(test_wave, test_flux, cache_name=\"B\", nmc=50)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9ae1daa",
   "metadata": {},
   "source": [
    "## Summary:\n",
    "\n",
    "- If you have very small RAM (<4GB), do not use the cache option\n",
    "- If you have large RAM, you can use **cache** method to speed up the RV measurements. It vectorizes the CCF evaluation on RV and template grid. It simply gives you about 10x speed.\n",
    "\n",
    "Tips: the cache size depends on \n",
    "- the number of templates\n",
    "- the spectral sampling rate of spectra\n",
    "- the RV grid\n",
    "Therefore, if you are working on a large number of templates, very dense RV grid, and high resolution spectra, be cautious! For LAMOST MRS spectra, the cache for the blue and red arms need about 2-3GB RAM.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6fbd8f7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
